package com.yohann.boot.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Objects;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * 请求上下文工具类
 *
 * @author Yeung Wah
 * @since 2021/5/8
 */
@Slf4j
public class WebUtils {

    private WebUtils() {
    }

    /**
     * 获取请求信息
     */
    private static ServletRequestAttributes getAttribute() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes()));
    }

    /**
     * 获取request对象
     */
    public static HttpServletRequest getRequest() {
        return getAttribute().getRequest();
    }

    /**
     * 获取response对象
     */
    public static HttpServletResponse getResponse() {
        return getAttribute().getResponse();
    }

    /**
     * 获取session对象
     */
    public static HttpSession getSession() {
        return getRequest().getSession();
    }

    /**
     * 获取请求者ip
     */
    public static String getRemoteAddr() {
        return getRequest().getRemoteAddr();
    }

    /**
     * 获取当前现场请求体
     *
     * @return 请求体字符串
     */
    public static String getRequestBody() {
        StringBuilder builder = new StringBuilder();

        try (InputStream inputStream = getRequest().getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, UTF_8))) {
            String line;
            while (Objects.nonNull(line = reader.readLine())) {
                builder.append(line);
            }
        } catch (Exception e) {
            log.error("getRequestBody出错！");
        }

        return builder.toString();
    }

    /**
     * 获取反序列化后的请求体
     *
     * @param clazz clazz
     * @param <T>   <T>
     * @return 请求体
     */
    public static <T> T getRequestBody(Class<T> clazz) {
        String requestBody = getRequestBody();
        return JSON.parseObject(requestBody, clazz);
    }

    /**
     * 获取反序列化后的请求体
     *
     * @param typeReference typeReference
     * @param <T>           <T>
     * @return 请求体
     */
    public static <T> T getRequestBody(TypeReference<T> typeReference) {
        String requestBody = getRequestBody();
        return JSON.parseObject(requestBody, typeReference);
    }

    /**
     * 获取请求体
     *
     * @param headerName 请求体名称
     * @param <T>
     * @return
     */
    @SuppressWarnings("all")
    public static <T> T getHeader(String headerName) {
        return (T) getRequest().getHeader(headerName);
    }

    /**
     * 获取session属性
     *
     * @param attributeName 属性名称
     * @param <T>           <T>
     * @return session属性
     */
    @SuppressWarnings("all")
    public static <T> T getSessionAttribute(String attributeName) {
        return (T) getSession().getAttribute(attributeName);
    }

    /**
     * 获取Cookie
     *
     * @return 返回Cookies
     */
    public static Cookie[] getCookies() {
        return getRequest().getCookies();
    }

    /**
     * 获取cookie
     *
     * @param cookieName cookie名称
     * @return cookie值
     */
    public static String getCookie(String cookieName) {
        for (Cookie cookie : getCookies()) {
            if (cookie.getName().equals(cookieName)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}